﻿
using UnityEngine;

namespace WssUtils
{

    /// <summary>
    /// 输入状态切换,适合ACT等需要判断按键 按下、松开、长按、轻击 的按钮
    /// 也可以用于状态切换的检测
    /// </summary>
    public class InputState
    {
        /// <summary>
        /// 刚刚按下了按钮
        /// </summary>
        public bool OnPressed = false;
        /// <summary>
        /// 刚刚释放了按钮
        /// </summary>
        public bool OnReleased = false;
        /// <summary>
        /// 按钮正在按住
        /// </summary>
        public bool IsPressing = false;

        private bool curState = false;
        private bool lastState = false;
        private WssUtils.Timer extendTimer = new WssUtils.Timer(1);
        private WssUtils.Timer delayTimer = new WssUtils.Timer(1);

        public float delayDuration = 0f;
        public float extendDuration = 0;

        /// <summary>
        /// 延迟时间(按钮松开之后，还会生效)
        /// </summary>
        public bool IsExtending = false;
        /// <summary>
        /// 延迟时间(按钮按下后，一段时间才会生效)
        /// </summary>
        public bool IsDelaying = false;

        /// <summary>
        /// 延迟输入的按下和松开，防止状态持续切换
        /// </summary>
        /// <returns></returns>
        public bool IsHolding { get => (IsPressing && !IsDelaying) || IsExtending; }

        /// <summary>
        /// 长按时间，是从触发长按才开始算起的时间，可以用来制作蓄力的计算
        /// </summary>
        /// <value></value>
        public float HoldingTime { get => delayTimer.ElapseTime - delayTimer.duration; }

        /// <summary>
        /// 刚刚触发状态/按钮的瞬间
        /// </summary>
        /// <value></value>
        public bool OnTap { get => OnReleased && IsDelaying; }

        /// <summary>
        /// 刚刚状态 长按触发
        /// </summary>
        /// <value></value>
        public bool OnHoldReleased { get => OnReleased && !IsDelaying; }

        public InputState(float delayTime = 0, float extendTime = 0)
        {
            this.extendDuration = extendTime;
            this.delayDuration = delayTime;
        }

        /// <summary>
        /// 使用tick 驱动逻辑，如果是AI 可以自己控制 一些参数的bool值来操作
        /// </summary>
        /// <param name="input"></param>
        /// <param name="dt"></param>
        public void Tick(bool input, float dt = -1)
        {
            if (dt == -1)
            {
                dt = Time.deltaTime;
            }

            extendTimer.Tick();
            delayTimer.Tick();

            curState = input;
            IsPressing = curState;

            OnPressed = false;
            OnReleased = false;
            IsExtending = false;
            IsDelaying = false;

            if (curState != lastState)
            {
                if (curState == true)
                {
                    OnPressed = true;
                    StartTimer(delayTimer, delayDuration);
                }
                else
                {
                    OnReleased = true;
                    StartTimer(extendTimer, extendDuration);
                }
            }

            lastState = curState;

            if (extendTimer.IsRunning)
            {
                IsExtending = true;
            }

            if (delayTimer.IsRunning)
            {
                IsDelaying = true;
            }

        }

        private void StartTimer(Timer timer, float duration)
        {
            timer.StartTimer(duration);
        }

    }


}